<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        function createTask(i) {
            return () => {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        resolve(i)
                    }, 2000);
                })
            }
        }
        class TaskQ {
            constructor(){
                this.max = 10;
                this.taskList = [];
                setTimeout(()=>{
                    this.run();
                });
            }
            addTask(task) {
                this.taskList.push(task);
            }
            run() {
                const length = this.taskList.length;
                if(!length){
                    return;
                }
                const min = Math.min(this.max, length);
                for (let i=0; i<min; i++) {
                    // 开始占用一个任务的空间
                    this.max--;
                    const task =this.taskList.shift();
                    task().then(res => {
                        console.log(res);
                    }).catch(error => {
                        console.log(error);
                    }).finally(() => {
                        // 释放一个任务空间
                        this.max++;
                        this.run();
                    })
                }
            }
        }
        const taskQ = new TaskQ();
        for(let i = 0;i<20;i++){
            const task = createTask(i);
            taskQ.addTask(task);
        }
        console.log(taskQ);
    </script>
</body>
</html>